/*
 * File Name:drv_iwdg_rtt.c
 * Version:v1.0.0
 * Change Logs:
 * Date             Author          main change
 * 2025-01-20       lanxin          the first version
 *
*/

/********************************************* READ ME BEGIN *************************************************************/

/* Brief:
 *
 * *1.适配 mal_iwdg。
 *
 */

/* Notice:
 *
 * * 1.基于 RT_Thread iwdg driver。
 *
 * * 2.喂狗在空闲线程里面。
 *
 */

/********************************************* READ ME END ***************************************************************/

/* source file */
#include "rtthread.h"
#include "rtdevice.h"

#include "mal_iwdg.h"

#ifdef ENABLE_IWDG
/* debug define */

/* private define */
#ifndef IWDG_TIMEOUT
    #define IWDG_TIMEOUT 5
#endif

#define IWDG_DEV_NAME "wdt"

/* function declaration */

/* variable declaration */

static s_iwdg_ops_t iwdg_ops;
static rt_device_t wdg_dev = RT_NULL;
static uint8_t init_state = 0;

static void iwdg_test_entry ( void *para )
{
    while ( 1 );
}

static int test_iwdg ( void )
{
    rt_thread_t t_test = rt_thread_create ( "iwdg", iwdg_test_entry, 0, 512, 0, 10 );

    if ( t_test )
        rt_thread_startup ( t_test );

    return 0;
}

static void iwdg_feed_dog ( void )
{
  if ( wdg_dev )
      rt_device_control ( wdg_dev, RT_DEVICE_CTRL_WDT_KEEPALIVE, NULL );
}

static void iwdg_init ( uint16_t timeout )
{
    if ( init_state )
        return;

    rt_err_t ret;

    /* find iwdg device */
    wdg_dev = rt_device_find ( IWDG_DEV_NAME );

    if ( wdg_dev == 0 )
    {
        rt_kprintf ( "iwdg dev do not find\r\n" );
        return ;
    }

    /* initial iwdg device */
    ret = rt_device_init ( wdg_dev );

    if ( ret != RT_EOK )
    {
        rt_kprintf ( "initialize iwdg failed!\n" );
        return ;
    }

    uint16_t iwdg_timeout = timeout ? timeout : IWDG_TIMEOUT;

    /* set iwdg timeout */
    ret = rt_device_control ( wdg_dev, RT_DEVICE_CTRL_WDT_SET_TIMEOUT, &iwdg_timeout );

    if ( ret != RT_EOK )
    {
        rt_kprintf ( "set iwdg timeout failed!\n" );
        return ;
    }

    /* start iwdg */
    ret = rt_device_control ( wdg_dev, RT_DEVICE_CTRL_WDT_START, RT_NULL );

    if ( ret != RT_EOK )
    {
        rt_kprintf ( "start iwdg failed!\n" );
        return;
    }

    init_state = 1;
}

int bsp_iwdg_init ( void )
{
    iwdg_ops.init = iwdg_init;
    iwdg_ops.refresh = iwdg_feed_dog;

    mal_iwdg_bind_ops ( &iwdg_ops );
    mal_iwdg_init ( IWDG_TIMEOUT );

    /* feed dog at idle hook */
    rt_thread_idle_sethook ( iwdg_feed_dog );

    return 0;
}

/* 导出到初始化列表 */
INIT_BOARD_EXPORT ( bsp_iwdg_init );

/* 导出到 MSH 命令列表 */
MSH_CMD_EXPORT ( test_iwdg, iwdg_test );

#endif
